﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace CrossQuery
{
    public class CrossQueryLoader
    {
        /// <summary>
        /// This xml file contain query information
        /// </summary>
        private string query_path = @"query.xml";
        private List<KeyValuePair<string, FreeQuery>> query_list;

        public CrossQueryLoader() { Load(); }

        public CrossQueryLoader(string path)
        {
            query_path = path;
            Load();
        }

        public List<string> QueryNames
        {
            get
            {
                List<string> res = new List<string>();
                foreach (var pair in query_list)
                {
                    res.Add(pair.Key);
                }
                return res;
            }
        }

        public FreeQuery GetCrossQuery(string query_name)
        {
            foreach (var pair in query_list)
            {
                if (pair.Key == query_name)
                    return pair.Value;
            }
            return null;
        }

        private void Load()
        {
            query_list = new List<KeyValuePair<string, FreeQuery>>();
            XmlDocument doc = new XmlDocument();
            doc.Load(query_path);
            foreach (XmlElement query_ele in doc.DocumentElement)
            {
                if (query_ele.Name == "query")
                {
                    FreeQuery cq = new FreeQuery();
                    string cq_name = "";

                    // read the information of query config file
                    foreach (XmlNode info_node in query_ele.ChildNodes)
                    {
                        Console.WriteLine(info_node.Name);
                        switch (info_node.Name)
                        {
                            case "name":
                                cq_name = info_node.InnerText;
                                Console.WriteLine("\t" + info_node.InnerText);
                                break;
                            case "display_name":
                                cq.SetDisplayName(info_node.InnerText);
                                break;
                            case "sql":
                                cq.SetSQL(info_node.InnerText);
                                break;
                            case "parameters":
                                foreach (XmlNode param_node in info_node.ChildNodes)
                                {
                                    string dp_name = "", type = "";
                                    foreach (XmlNode param_info_node in param_node.ChildNodes)
                                    {
                                        switch (param_info_node.Name)
                                        {
                                            case "display_name":
                                                dp_name = param_info_node.InnerText;
                                                break;
                                            case "type":
                                                type = param_info_node.InnerText;
                                                break;
                                        }
                                    }
                                    cq.AddParameter(dp_name, type);
                                }
                                break;
                            case "output_fields":
                                foreach (XmlNode field_node in info_node.ChildNodes)
                                {
                                    foreach (XmlNode field_info_node in field_node.ChildNodes)
                                    {
                                        switch (field_info_node.Name)
                                        { 
                                            case "name":
                                                cq.AddOutputDatabaseName(field_info_node.InnerText);
                                                break;
                                            case "display_name":
                                                cq.AddOutputDisplayName(field_info_node.InnerText);
                                                break;
                                        }
                                    }
                                }
                                break;
                            case "chart_type":
                                cq.SetChartType(info_node.InnerText);
                                break;
                        }
                    }
                    // add cross query to list
                    query_list.Add(new KeyValuePair<string,FreeQuery>(cq_name, cq));
                }
            }
        }
    }
}
